﻿Imports System
Imports System.Collections
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Friend NotInheritable Class ResizingMessageFilter
        Inherits WorkflowDesignerMessageFilter
        ' Methods
        Private Function CanResizeDesigner(ByVal designer As ActivityDesigner) As Boolean
            If Not designer.EnableVisualResizing Then
                Return False
            End If
            If (designer.ParentDesigner Is Nothing) Then
                Return True
            End If
            Dim parentDesigner As FreeformActivityDesigner = [TryCast](designer.ParentDesigner,FreeformActivityDesigner)
            Return ((Not parentDesigner Is Nothing) AndAlso parentDesigner.CanResizeContainedDesigner(designer))
        End Function

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            MyBase.Dispose(disposing)
        End Sub

        Private Function GetDesignerToResize(ByVal point As Point, <Out> ByRef sizingEdge As DesignerEdges) As ActivityDesigner
            Dim designer As ActivityDesigner = Nothing
            sizingEdge = DesignerEdges.None
            Dim service As ISelectionService = [TryCast](MyBase.GetService(GetType(ISelectionService)),ISelectionService)
            If (Not service Is Nothing) Then
                Dim list As New ArrayList(service.GetSelectedComponents)
                Dim i As Integer = 0
                Do While ((i < list.Count) AndAlso (designer Is Nothing))
                    Dim activity As Activity = [TryCast](list.Item(i),Activity)
                    If (Not activity Is Nothing) Then
                        Dim designer2 As ActivityDesigner = ActivityDesigner.GetDesigner(activity)
                        If (Not designer2 Is Nothing) Then
                            Dim glyph As SelectionGlyph = [TryCast](designer2.Glyphs.Item(GetType(SelectionGlyph)),SelectionGlyph)
                            If (Not glyph Is Nothing) Then
                                Dim rectangle As Rectangle
                                For Each rectangle In glyph.GetGrabHandles(designer2)
                                    If rectangle.Contains(point) Then
                                        designer = designer2
                                        sizingEdge = Me.GetSizingEdge(designer, point)
                                        Exit For
                                    End If
                                Next
                            End If
                        End If
                    End If
                    i += 1
                Loop
            End If
            Return designer
        End Function

        Private Function GetSizingEdge(ByVal designer As ActivityDesigner, ByVal point As Point) As DesignerEdges
            Dim none As DesignerEdges = DesignerEdges.None
            Dim selectionSize As Size = WorkflowTheme.CurrentTheme.AmbientTheme.SelectionSize
            Dim bounds As Rectangle = designer.Bounds
            Dim line As Point() = New Point() { New Point(bounds.Left, bounds.Top), New Point(bounds.Left, bounds.Bottom) }
            If (Math.Floor(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, line)) <= (selectionSize.Width + 1)) Then
                none = (none Or DesignerEdges.Left)
            End If
            Dim pointArray2 As Point() = New Point() { New Point(bounds.Left, bounds.Top), New Point(bounds.Right, bounds.Top) }
            If (Math.Floor(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, pointArray2)) <= (selectionSize.Height + 1)) Then
                none = (none Or DesignerEdges.Top)
            End If
            Dim pointArray3 As Point() = New Point() { New Point(bounds.Right, bounds.Top), New Point(bounds.Right, bounds.Bottom) }
            If (Math.Floor(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, pointArray3)) <= (selectionSize.Width + 1)) Then
                none = (none Or DesignerEdges.Right)
            End If
            Dim pointArray4 As Point() = New Point() { New Point(bounds.Left, bounds.Bottom), New Point(bounds.Right, bounds.Bottom) }
            If (Math.Floor(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, pointArray4)) <= (selectionSize.Height + 1)) Then
                none = (none Or DesignerEdges.Bottom)
            End If
            Return none
        End Function

        Protected Overrides Function OnKeyDown(ByVal eventArgs As KeyEventArgs) As Boolean
            If ((eventArgs.KeyValue = &H1B) AndAlso (Not Me.designerToResize Is Nothing)) Then
                Me.SetResizableDesigner(Nothing, DesignerEdges.None)
                Return True
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseCaptureChanged() As Boolean
            If (Not Me.designerToResize Is Nothing) Then
                Me.SetResizableDesigner(Nothing, DesignerEdges.None)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseDown(ByVal eventArgs As MouseEventArgs) As Boolean
            If (eventArgs.Button = MouseButtons.Left) Then
                Dim parentView As WorkflowView = MyBase.ParentView
                If (parentView Is Nothing) Then
                    Throw New InvalidOperationException(DR.GetString("WorkflowViewNull", New Object(0  - 1) {}))
                End If
                Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
                Dim point As Point = parentView.ClientPointToLogical(clientPoint)
                Dim none As DesignerEdges = DesignerEdges.None
                Dim designerToResize As ActivityDesigner = Me.GetDesignerToResize(point, none)
                If (((Not designerToResize Is Nothing) AndAlso (none <> DesignerEdges.None)) AndAlso Me.CanResizeDesigner(designerToResize)) Then
                    Me.SetResizableDesigner(designerToResize, none)
                End If
            End If
            Return (Not Me.designerToResize Is Nothing)
        End Function

        Protected Overrides Function OnMouseLeave() As Boolean
            If (Not Me.designerToResize Is Nothing) Then
                Me.SetResizableDesigner(Nothing, DesignerEdges.None)
            Else
                Me.UpdateCursor(DesignerEdges.None)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseMove(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim parentView As WorkflowView = MyBase.ParentView
            If (parentView Is Nothing) Then
                Throw New InvalidOperationException(DR.GetString("WorkflowViewNull", New Object(0  - 1) {}))
            End If
            Dim flag As Boolean = False
            Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
            Dim point As Point = parentView.ClientPointToLogical(clientPoint)
            Dim none As DesignerEdges = DesignerEdges.None
            If (Not Me.designerToResize Is Nothing) Then
                none = Me.designerSizingEdge
                Me.UpdateDesignerSize(point, Me.designerToResize, Me.designerSizingEdge)
                flag = True
            ElseIf (eventArgs.Button = MouseButtons.None) Then
                Dim designerToResize As ActivityDesigner = Me.GetDesignerToResize(point, none)
                If (((Not designerToResize Is Nothing) AndAlso (none <> DesignerEdges.None)) AndAlso Me.CanResizeDesigner(designerToResize)) Then
                    flag = True
                End If
            End If
            Me.UpdateCursor(none)
            Return flag
        End Function

        Protected Overrides Function OnMouseUp(ByVal eventArgs As MouseEventArgs) As Boolean
            If ((Not Me.designerToResize Is Nothing) AndAlso (eventArgs.Button = MouseButtons.Left)) Then
                Dim parentView As WorkflowView = MyBase.ParentView
                If (parentView Is Nothing) Then
                    Throw New InvalidOperationException(DR.GetString("WorkflowViewNull", New Object(0  - 1) {}))
                End If
                Me.UpdateDesignerSize(parentView.ClientPointToLogical(New Point(eventArgs.X, eventArgs.Y)), Me.designerToResize, Me.designerSizingEdge)
            End If
            Me.SetResizableDesigner(Nothing, DesignerEdges.None)
            Return False
        End Function

        Private Sub SetResizableDesigner(ByVal designer As ActivityDesigner, ByVal sizingEdge As DesignerEdges)
            If ((Not Me.designerToResize Is designer) AndAlso ((designer Is Nothing) OrElse Me.CanResizeDesigner(designer))) Then
                Dim parentView As WorkflowView = MyBase.ParentView
                If (parentView Is Nothing) Then
                    Throw New InvalidOperationException(DR.GetString("WorkflowViewNull", New Object(0  - 1) {}))
                End If
                If (Not designer Is Nothing) Then
                    If (Not Me.designerTransaction Is Nothing) Then
                        Me.designerTransaction.Cancel
                    End If
                    Dim service As IDesignerHost = [TryCast](MyBase.GetService(GetType(IDesignerHost)),IDesignerHost)
                    If (Not service Is Nothing) Then
                        Me.designerTransaction = service.CreateTransaction(DR.GetString("ResizeUndoDescription", New Object() { designer.Text }))
                    End If
                    DirectCast(designer, IWorkflowDesignerMessageSink).OnBeginResizing(sizingEdge)
                Else
                    If (Not Me.designerTransaction Is Nothing) Then
                        Me.designerTransaction.Commit
                        Me.designerTransaction = Nothing
                    End If
                    DirectCast(Me.designerToResize, IWorkflowDesignerMessageSink).OnEndResizing
                End If
                Me.designerToResize = designer
                Me.designerSizingEdge = sizingEdge
                parentView.Capture = (Not Me.designerToResize Is Nothing)
                Me.UpdateCursor(Me.designerSizingEdge)
            End If
        End Sub

        Private Sub UpdateCursor(ByVal sizingEdge As DesignerEdges)
            Dim parentView As WorkflowView = MyBase.ParentView
            If (parentView Is Nothing) Then
                Throw New InvalidOperationException(DR.GetString("WorkflowViewNull", New Object(0  - 1) {}))
            End If
            Dim sizeNWSE As Cursor = parentView.Cursor
            If ((((sizingEdge And DesignerEdges.Left) > DesignerEdges.None) AndAlso ((sizingEdge And DesignerEdges.Top) > DesignerEdges.None)) OrElse (((sizingEdge And DesignerEdges.Right) > DesignerEdges.None) AndAlso ((sizingEdge And DesignerEdges.Bottom) > DesignerEdges.None))) Then
                sizeNWSE = Cursors.SizeNWSE
            ElseIf ((((sizingEdge And DesignerEdges.Right) > DesignerEdges.None) AndAlso ((sizingEdge And DesignerEdges.Top) > DesignerEdges.None)) OrElse (((sizingEdge And DesignerEdges.Left) > DesignerEdges.None) AndAlso ((sizingEdge And DesignerEdges.Bottom) > DesignerEdges.None))) Then
                sizeNWSE = Cursors.SizeNESW
            ElseIf (((sizingEdge And DesignerEdges.Top) > DesignerEdges.None) OrElse ((sizingEdge And DesignerEdges.Bottom) > DesignerEdges.None)) Then
                sizeNWSE = Cursors.SizeNS
            ElseIf (((sizingEdge And DesignerEdges.Left) > DesignerEdges.None) OrElse ((sizingEdge And DesignerEdges.Right) > DesignerEdges.None)) Then
                sizeNWSE = Cursors.SizeWE
            ElseIf ((sizingEdge = DesignerEdges.None) AndAlso (((parentView.Cursor Is Cursors.SizeNWSE) OrElse (parentView.Cursor Is Cursors.SizeNESW)) OrElse ((parentView.Cursor Is Cursors.SizeNS) OrElse (parentView.Cursor Is Cursors.SizeWE)))) Then
                sizeNWSE = Cursors.Default
            End If
            If (Not parentView.Cursor Is sizeNWSE) Then
                parentView.Cursor = sizeNWSE
            End If
        End Sub

        Private Sub UpdateDesignerSize(ByVal point As Point, ByVal designerToSize As ActivityDesigner, ByVal sizingEdge As DesignerEdges)
            If (MyBase.ParentView Is Nothing) Then
                Throw New InvalidOperationException(DR.GetString("WorkflowViewNull", New Object(0  - 1) {}))
            End If
            Dim empty As Rectangle = Rectangle.Empty
            If (Not designerToSize.ParentDesigner Is Nothing) Then
                empty = designerToSize.ParentDesigner.Bounds
                Dim selectionSize As Size = WorkflowTheme.CurrentTheme.AmbientTheme.SelectionSize
                empty.Inflate((-2 * selectionSize.Width), (-2 * selectionSize.Height))
            End If
            Dim bounds As Rectangle = designerToSize.Bounds
            If ((sizingEdge And DesignerEdges.Left) > DesignerEdges.None) Then
                Dim x As Integer = point.X
                If Not empty.IsEmpty Then
                    x = Math.Max(x, empty.X)
                End If
                x = DesignerHelpers.SnapToGrid(New Point(x, 0)).X
                bounds.Width = (bounds.Width + (bounds.Left - x))
                Dim num2 As Integer = If((bounds.Width < designerToSize.MinimumSize.Width), (bounds.Width - designerToSize.MinimumSize.Width), 0)
                bounds.X = (x + num2)
            End If
            If ((sizingEdge And DesignerEdges.Top) > DesignerEdges.None) Then
                Dim y As Integer = point.Y
                If Not empty.IsEmpty Then
                    y = Math.Max(y, empty.Y)
                End If
                y = DesignerHelpers.SnapToGrid(New Point(0, y)).Y
                bounds.Height = (bounds.Height + (bounds.Top - y))
                Dim num4 As Integer = If((bounds.Height < designerToSize.MinimumSize.Height), (bounds.Height - designerToSize.MinimumSize.Height), 0)
                bounds.Y = (y + num4)
            End If
            If ((sizingEdge And DesignerEdges.Right) > DesignerEdges.None) Then
                bounds.Width = (bounds.Width + (point.X - bounds.Right))
            End If
            If ((sizingEdge And DesignerEdges.Bottom) > DesignerEdges.None) Then
                bounds.Height = (bounds.Height + (point.Y - bounds.Bottom))
            End If
            bounds.Width = Math.Max(bounds.Width, designerToSize.MinimumSize.Width)
            bounds.Height = Math.Max(bounds.Height, designerToSize.MinimumSize.Height)
            If Not empty.IsEmpty Then
                bounds = Rectangle.Intersect(bounds, empty)
            End If
            DirectCast(designerToSize, IWorkflowDesignerMessageSink).OnResizing(sizingEdge, bounds)
        End Sub


        ' Fields
        Private designerSizingEdge As DesignerEdges
        Private designerToResize As ActivityDesigner
        Private designerTransaction As DesignerTransaction
    End Class
End Namespace

